//
// Created by 33145 on 2023/6/2.
//

#ifndef ROCKET_TCP_CONNECTION_H
#define ROCKET_TCP_CONNECTION_H

#include <memory>
#include <map>
#include <queue>

// #include "tcp_server.h"
#include "net_addr.h"
#include "tcp_buffer.h"
#include "../net/io_thread.h"
#include "../coder/abstract_protocol.h"
#include "../coder/abstract_coder.h"
#include "../rpc/rpc_dispatcher.h"

namespace rocket {
  // read ---> rpc_request ---> execute ---> rpc_response ---> onRead
  // 服务器： read ---> execute ---> write
  // 客户端： write ---> read ---> execute
  class TCPConnection {
  public:
    enum TcpState {
      NotConnected = 1,
      Connected = 2,
      HalfClosing = 3,
      Closed = 4,
    };

    enum TcpConnectionType {
      TcpConnectionByServer = 1,  // 作为服务端使用，代表跟对端客户端的连接
      TcpConnectionByClient = 2,  // 作为客户端使用，代表跟对赌服务端的连接
    };

  public:
    typedef std::shared_ptr<TCPConnection> ptr;

    TCPConnection(EventLoop::ptr event_loop, int fd, int buffer_size,
                  NetAddr::ptr peer_addr, NetAddr::ptr local_addr, TcpConnectionType connection_type = TcpConnectionByServer);
    ~TCPConnection();

    void onRead();
    void onWrite();
    void execute();
    void clear();
    void shutDown();  // 主动关闭连接

    void listenWrite();  // 监听可写事件
    void listenRead();   // 监听可读事件
    void pushSendMessage(const AbstractProtocol::ptr& message, const std::function<void(AbstractProtocol::ptr)>& done);
    void pushReadMessage(const std::string& req_id, const std::function<void(AbstractProtocol::ptr)>& done);

    void setState(const TCPConnection::TcpState value) { _state = value; }
    void setConnectionType(const TCPConnection::TcpConnectionType value) {
      _connection_type = value;
    }

    NetAddr::ptr getLocalAddr() { return _local_addr; }
    NetAddr::ptr getPeerAddr() { return _peer_addr; }

    TCPConnection::TcpState getState() { return _state; }

  private:
    NetAddr::ptr _local_addr;
    NetAddr::ptr _peer_addr;

    TCPBuffer::ptr _in_buffer;           // 接收缓冲区
    TCPBuffer::ptr _out_buffer;

    EventLoop::ptr _event_loop {nullptr};  // 当前连接所在的event loop
    FdEvent::ptr _fd_event {nullptr};
    int _fd;

    TcpState _state;

    TcpConnectionType _connection_type {TcpConnectionByServer};

    std::vector<std::pair<AbstractProtocol::ptr, std::function<void(AbstractProtocol::ptr)>>> _write_dones;

    // key：msg_id 请求/响应号  value: 相应回调
    std::map<std::string, std::function<void(AbstractProtocol::ptr)>> _read_dones;

    AbstractCoder::ptr _coder {nullptr};

  };
}

#endif //ROCKET_TCP_CONNECTION_H
